#!-*- coding:utf8 -*-

__author__='loda'

import os
import datetime
import time
import json
import requests
import logging

#counting data delta seconds before
delta=60

#interval
step=60
ct="GAUGE"
tags=""

logpath="/log/falcon-collector/collector.log"
basepath="/data/monitor/statistics"
url="http://10.100.52.166:1988/v1/push"
types=[
	"provider.success","consumer.success",
	"provider.elapsed","consumer.elapsed",
	"provider.failure","consumer.failure",
	"provider.concurrent","consumer.concurrent",
	"provider.max.elapsed","consumer.max.elapsed",
	"provider.max.concurrent","consumer.max.concurrent"
      ]

#config log info
logging.basicConfig(level=logging.INFO,filename=logpath)

#send data to open-falcon
def send(endpoint,metric,ts,value):
  payload=[
    {
        "endpoint": endpoint,
        "metric": metric,
	"timestamp": ts,
	"step": step,
	"value": value,
       	"counterType": ct,
	"tags": tags
    }
  ]

  r=requests.post(url,data=json.dumps(payload))
  logging.info(r.text)
  logging.info("data is:%s",json.dumps(payload))

#search files
def search(dirname,tp,files):
  for filename in os.listdir(dirname):
    absfile=dirname+os.sep+filename
    if os.path.isfile(absfile):
      if filename==tp:
        files.append(absfile)
    else:
      search(absfile,tp,files)
  return files

#list all services in current minute this day 
def listServices(current_day,current_minute):
  services=[]
  for x in os.listdir(basepath):
    if x==current_day:
      for s in os.listdir(basepath+os.sep+x):
        services.append(basepath+os.sep+x+os.sep+s)
  return services
 
#list all methods in services
def listMethods(services):
  methods=[]
  for s in services:
    for m in os.listdir(s):
      methods.append(s+os.sep+m)
  return methods

#count data of the method
def count(method,current_minute):
  metric={}
  for t in types:
    files=search(method,t,[])
    for filename in files:
      with open(filename,"r") as f:
        for line in f.readlines():
          record=line.split(" ")
          key=record[0]
          value=int(record[1])
	  if key==current_minute:
	    if t in metric:
              if "max" in t:
	        metric[t]=max(metric[t],value)
	      else:
	        metric[t]=metric[t]+value
	    else:
	      metric[t]=value
  return metric

#calculate for final metric
def calculate(metric):
  final_metric={}
  for k in metric:
    if "max" in k:
      final_metric[k]=metric[k]
    elif k.endswith(".elapsed"):
      index=k.rfind(".")
      final_metric[k]=round(1.0*metric[k]/metric[k[0:index]+".success"],2)
    else:
      final_metric[k]=round(1.0*metric[k]/60,2)
  return final_metric

#extract service and method from path
def extractMethod(path):
  index=path.rfind("/")
  methodName=path[index+1:]
  index0=path[0:index].rfind("/")
  serviceName=path[index0+1:index]
  return serviceName+"&"+methodName

#collect data
def collect():
  now=datetime.datetime.now()
  #couting date delta seconds before
  now=now-datetime.timedelta(seconds=delta)
  current_time=int(time.time()-delta)
  current_day=now.strftime('%Y%m%d')
  current_minute=now.strftime('%H%M')
  
  logging.info("execute collect at %s",now.strftime('%Y-%m-%d %H:%M:%S'))

  services=listServices(current_day,current_minute)
  methods=listMethods(services)

  for m	in methods:
    method=extractMethod(m)
    metric=count(m,current_minute)
    final_metric=calculate(metric)
    for k in final_metric:
      send(method,k,current_time,final_metric[k])

#execute task at fixed rate
def executeAtFixedRate(second):
  while True:
    collect()
    time.sleep(second)

if __name__=='__main__':
  executeAtFixedRate(step)
